package com.sanbi.erp.db.service;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;
import com.sanbi.common.util.JacksonUtil;
import com.sanbi.common.util.StringUtil;
import com.sanbi.erp.core.system.ErrorEnum;
import com.sanbi.erp.core.util.BarCodeUtil;
import com.sanbi.erp.core.util.OkHttpUtil;
import com.sanbi.erp.core.util.itextpdf.PdfUtil;
import com.sanbi.erp.core.vo.PNGUploadRespVo;
import com.sanbi.erp.db.config.BizException;
import com.sanbi.erp.db.domain.*;
import com.sanbi.erp.db.domain.*;
import com.sanbi.erp.db.util.CheckoutUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.imageio.ImageIO;

import com.sanbi.erp.db.dao.ProductMapper;
import org.springframework.transaction.annotation.Transactional;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public class ProductService{

    @Resource
    private ProductMapper productMapper;
    @Resource
    private StoreProductService storeProductService;
    @Resource
    private ProductGroupService productGroupService;

    public int deleteByPrimaryKey(Integer id) {
        return productMapper.deleteByPrimaryKey(id);
    }


    public int insert(Product record) {
        return productMapper.insert(record);
    }


    public int insertSelective(Product record) {
        return productMapper.insertSelective(record);
    }

    public Product selectByPrimaryKey(Integer id) {
        return productMapper.selectByPrimaryKey(id);
    }


    public int updateByPrimaryKeySelective(Product record) {
        return productMapper.updateByPrimaryKeySelective(record);
    }


    public int updateByPrimaryKey(Product record) {
        return productMapper.updateByPrimaryKey(record);
    }

    /**
     * 单个商品新增
     * @param product
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int insertSelectiveAdd(Product product) {
        // 校验sku是否存在
        List<String> list = new ArrayList<>();
        list.add(product.getProductSku());
        List<Product> productList = this.productMapper.selectListBySKU(list, list.get(CheckoutUtil.TYPE_ZERO));
        if (productList.size() > CheckoutUtil.TYPE_ZERO) {
            throw new BizException(ErrorEnum.ErrorCode.authInvalidPassword);
        }
        // 获取店铺货品信息
        StoreProduct[] storeProduct = product.getStoreProduct();
        // 生成商品/货品sku
        // String productSku = Generator.createProductSku(Enums.ObjectType.ProductSku);
        // product.setProductSku(productSku);
        product.setAddTime(LocalDateTime.now());
        product.setUpdateTime(LocalDateTime.now());
        product.setDeleted(false);
        if (productMapper.insertSelective(product) <= 0) {
            throw new BizException(ErrorEnum.ErrorCode.InsertUnsuccessful);
        }
        // 批量新增店铺商品
        if (storeProduct.length > 0) {
            // ArrayList<StoreProduct> storeProductArrayList = new ArrayList<>(Arrays.asList(storeProduct));
            ArrayList<StoreProduct> storeProductArrayList = new ArrayList<>();
            for (StoreProduct storeProductOne : storeProduct) {
                storeProductOne.setProductId(product.getId());
                storeProductOne.setAddTime(LocalDateTime.now());
                storeProductOne.setUpdateTime(LocalDateTime.now());
                storeProductOne.setDeleted(false);
                storeProductArrayList.add(storeProductOne);
            }
            if (this.storeProductService.insertSelectiveList(storeProductArrayList) <= 0) {
                throw new BizException(ErrorEnum.ErrorCode.InsertUnsuccessful);
            }
        }
        return CheckoutUtil.TYPE_ONE;
    }

    /**
     * 单个商品新增（组合商品）
     * @param product
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int insertSelectiveAddGroup(Product product, List<ProductGroup> productGroupList) {
        // 校验sku是否存在
        List<String> list = new ArrayList<>();
        list.add(product.getProductSku());
        List<Product> productList = this.productMapper.selectListBySKU(list, list.get(CheckoutUtil.TYPE_ZERO));
        if (productList.size() > CheckoutUtil.TYPE_ZERO) {
            throw new BizException(ErrorEnum.ErrorCode.authInvalidPassword);
        }
        // 商品表添加
        product.setProductIsGroup(true);
        product.setAddTime(LocalDateTime.now());
        product.setUpdateTime(LocalDateTime.now());
        product.setDeleted(false);
        if (productMapper.insertSelective(product) <= 0) {
            throw new BizException(ErrorEnum.ErrorCode.InsertUnsuccessful);
        }
        // 获取店铺货品信息
        StoreProduct[] storeProduct = product.getStoreProduct();
        // 批量添加
        if (storeProduct.length > 0) {
            // ArrayList<StoreProduct> storeProductArrayList = new ArrayList<>(Arrays.asList(storeProduct));
            ArrayList<StoreProduct> storeProductArrayList = new ArrayList<>();
            for (StoreProduct storeProductOne : storeProduct) {
                storeProductOne.setProductId(product.getId());
                storeProductOne.setAddTime(LocalDateTime.now());
                storeProductOne.setUpdateTime(LocalDateTime.now());
                storeProductOne.setDeleted(false);
                storeProductArrayList.add(storeProductOne);
            }
            if (this.storeProductService.insertSelectiveList(storeProductArrayList) <= 0) {
                throw new BizException(ErrorEnum.ErrorCode.InsertUnsuccessful);
            }
        }
        // 组合商品表（批量新增）
        for (ProductGroup productGroup : productGroupList) {
            productGroup.setProductId(product.getId());
            productGroup.setAddTime(LocalDateTime.now());
            productGroup.setUpdateTime(LocalDateTime.now());
            productGroup.setDeleted(false);
        }
        if (this.productGroupService.insertSelectiveList(productGroupList) <= 0) {
            throw new BizException(ErrorEnum.ErrorCode.BadReqArgument);
        }
        return CheckoutUtil.TYPE_ONE;
    }

    /**
     * 单个商品编辑（单个/组合）
     * @param product
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int updateOne(Product product) {
        // 是否对店铺商品进行了修改
        if (product.getStoreProductList().size() > CheckoutUtil.TYPE_ZERO) {
            // 修改后的数据(新增数据)
            List<StoreProduct> storeProductListOne = product.getStoreProductList();
            // 修改前的数据
            List<StoreProduct> storeProductListTwo = this.storeProductService.selectByPrimaryKeyByList(product.getId());
            for (StoreProduct storeProduct : storeProductListTwo) {
                storeProduct.setDeleted(true);
                storeProduct.setUpdateTime(LocalDateTime.now());
            }
            // 批量逻辑删除
            if (this.storeProductService.updateByPrimaryKeySelectiveList(storeProductListTwo) <= CheckoutUtil.TYPE_ZERO) {
                throw new BizException(ErrorEnum.ErrorCode.UpdateUnsuccessful);
            }
            for (StoreProduct storeProduct : storeProductListOne) {
                storeProduct.setProductId(product.getId());
                storeProduct.setAddTime(LocalDateTime.now());
                storeProduct.setUpdateTime(LocalDateTime.now());
                storeProduct.setDeleted(false);
            }
            // 批量新增
            if (this.storeProductService.insertSelectiveList(storeProductListOne) <= CheckoutUtil.TYPE_ZERO) {
                throw new BizException(ErrorEnum.ErrorCode.InsertUnsuccessful);
            }
        }
        if (product.getProductIsGroup()) {
            // 是否对商品进行了修改（组合商品）
            if (product.getProductGroupList().size() > CheckoutUtil.TYPE_ZERO) {
                // 修改后的数据(新增数据)
                List<ProductGroup> productGroupListOne = product.getProductGroupList();
                // 修改前的数据
                List<ProductGroup> productGroupListTwo = this.productGroupService.selectByPrimaryKeyList(product.getId());

                for (ProductGroup productOne : productGroupListTwo) {
                    productOne.setDeleted(true);
                    productOne.setUpdateTime(LocalDateTime.now());
                }
                // 批量逻辑删除
                if (this.productGroupService.updateByPrimaryKeySelectiveList(productGroupListTwo) <= CheckoutUtil.TYPE_ZERO) {
                    throw new BizException(ErrorEnum.ErrorCode.UpdateUnsuccessful);
                }
                for (ProductGroup productTwo : productGroupListOne) {
                    productTwo.setProductId(product.getId());
                    productTwo.setAddTime(LocalDateTime.now());
                    productTwo.setUpdateTime(LocalDateTime.now());
                    productTwo.setDeleted(false);
                }
                // 批量新增
                if (this.productGroupService.insertSelectiveList(productGroupListOne) <= CheckoutUtil.TYPE_ZERO) {
                    throw new BizException(ErrorEnum.ErrorCode.InsertUnsuccessful);
                }
            }
        }
        product.setUpdateTime(LocalDateTime.now());
        if (productMapper.updateByPrimaryKeySelective(product) <= 0) {
            throw new BizException(ErrorEnum.ErrorCode.InsertUnsuccessful);
        }
        return CheckoutUtil.TYPE_ONE;
    }

    /**
     * 获取商品信息
     * @param body 查询条件
     * {detailsType 0 默认 1 库存sku 2 店铺sku 3 中文名称 4 英文名称 5 供应商,
     *  matching  0 默认 1 精确匹配 2 模糊匹配,
     *  message 查询内容,
     *  skuState sku状态 0 全部 1 正常销售，2 停止销售，3 清仓,
     *  categoryId 类目id 0 全部 }
     * @param page 页索引
     * @param limit 页大小
     * @return
     */
    public List<Product> selectLinkList(String body, Integer page, Integer limit) {
        Integer matching = JacksonUtil.parseInteger(body, "matching");
        Integer detailsType = JacksonUtil.parseInteger(body, "detailsType");
        String message = JacksonUtil.parseString(body, "message");
        Integer skuState = JacksonUtil.parseInteger(body, "skuState");
        Integer categoryId = JacksonUtil.parseInteger(body, "categoryId");
        if (CheckoutUtil.isEmptyInteger(matching)) matching = null;
        if (CheckoutUtil.isEmptyInteger(detailsType)) detailsType = null;
        PageHelper.startPage(page,limit);
        List<Product> productList = productMapper.selectLinkList(matching, detailsType, message, skuState, categoryId);
        // log.info("{}查询的数据：",productList);
        return productList;
    }

    /**
     * 获取商品信息（单商品）
     * @param body 查询条件
     * {detailsType 1 商品sku 2 店铺sku 3 中文名称 4 英文名称 5 供应商
     *  page 页索引
     *  limit 页大小}
     * @return
     */
    public List<Product> getListDoubleClick(String body, Integer page, Integer limit,List<String> list) {
        Integer detailsType = JacksonUtil.parseInteger(body, "detailsType");
        if (CheckoutUtil.isEmptyInteger(detailsType)) detailsType = null;
        PageHelper.startPage(page,limit);
        return productMapper.getListDoubleClick(detailsType,list,list.get(CheckoutUtil.TYPE_ZERO));
        // log.info("{}查询的数据：",productList);
//        return productList;
    }

    /**
     * 获取单个商品的信息
     * @return
     */
    public Product selectOne(Integer id) {
        return productMapper.selectOne(id);
    }

    /**
     * 获取单个商品的信息（组合商品）
     * @return
     */
    public Product selectOneGroup(Integer id) {
        return productMapper.selectOneGroup(id);
    }

    /**
     * 获取商品信息（组合商品）
     * @param body 查询条件
     * {detailsType 0 默认 1 库存sku 2 店铺sku 3 中文名称 4 英文名称 5 供应商,
     *  matching  0 默认 1 精确匹配 2 模糊匹配,
     *  message 查询内容,
     *  skuState sku状态 0 全部 1 正常销售，2 停止销售，3 清仓,
     *  categoryId 类目id 0 全部 }
     * @param page 页索引
     * @param limit 页大小
     * @return
     */
    public List<Product> selectLinkListGroup(String body, Integer page, Integer limit) {
        Integer matching = JacksonUtil.parseInteger(body, "matching");
        Integer detailsType = JacksonUtil.parseInteger(body, "detailsType");
        String message = JacksonUtil.parseString(body, "message");
        Integer skuState = JacksonUtil.parseInteger(body, "skuState");
        Integer categoryId = JacksonUtil.parseInteger(body, "categoryId");
        if (CheckoutUtil.isEmptyInteger(matching)) matching = null;
        if (CheckoutUtil.isEmptyInteger(detailsType)) detailsType = null;
        PageHelper.startPage(page,limit);
        // List<Product> productList = productMapper.selectLinkListGroup(matching, detailsType, message, skuState, categoryId);
        // return  productList;
        return  productMapper.selectLinkListGroup(matching, detailsType, message, skuState, categoryId);
    }


    /**
     * 查询商品信息 组合商品新增时使用（组合商品）
     * @param body 查询条件
     * {detailsType 1 库存sku  3 中文名称 4 英文名称,
     *  matching   1 精确匹配 2 模糊匹配,
     *  message 查询内容,}
     * @return
     */
    public List<Product> getListGroupBySku(String body) {
        Integer detailsType = JacksonUtil.parseInteger(body, "detailsType");
        Integer matching = JacksonUtil.parseInteger(body, "matching");
        String message = JacksonUtil.parseString(body, "message");
        if (CheckoutUtil.isEmptyInteger(matching)) matching = null;
        if (CheckoutUtil.isEmptyInteger(detailsType)) detailsType = null;
        return  productMapper.getListGroupBySku(matching, detailsType, message);
    }

    /**
     * 查询商品信息 新增采购计划时使用
     * @param body 查询条件
     * {detailsType 1 单个商品sku  2 组合商品sku,
     *  matching   1 精确匹配 2 模糊匹配,
     *  message 查询内容}
     * @return
     */
    public List<Product> getListByProductSku(String body) {
        Integer detailsType = JacksonUtil.parseInteger(body, "detailsType");
        Integer matching = JacksonUtil.parseInteger(body, "matching");
        String message = JacksonUtil.parseString(body, "message");
        if (CheckoutUtil.isEmptyInteger(matching)) matching = null;
        if (CheckoutUtil.isEmptyInteger(detailsType)) detailsType = null;
        return  productMapper.getListByProductSku(matching, detailsType, message);
    }

    /**
     * 批量导出
     * @param body 查询条件
     * {detailsType 0 默认 1 库存sku 2 店铺sku 3 中文名称 4 英文名称 5 供应商,
     *  matching  0 默认 1 精确匹配 2 模糊匹配,
     *  message 查询内容,
     *  sku状态 0 全部 1 正常销售，2 停止销售，3 清仓,
     *  categoryId 类目id 0 全部 }
     * @return
     */
    public List<ProductEasyExcelAdd> batchDeriveExcel(String body) {
        Integer matching = JacksonUtil.parseInteger(body, "matching");
        Integer detailsType = JacksonUtil.parseInteger(body, "detailsType");
        String message = JacksonUtil.parseString(body, "message");
        Integer skuState = JacksonUtil.parseInteger(body, "skuState");
        Integer categoryId = JacksonUtil.parseInteger(body, "categoryId");
        if (CheckoutUtil.isEmptyInteger(matching)) matching = null;
        if (CheckoutUtil.isEmptyInteger(detailsType)) detailsType = null;
        // 获取批量导出的数据
        return productMapper.batchDeriveExcel(matching, detailsType, message, skuState, categoryId);
    }

    /**
     * 批量导出（组合商品）
     * @param body 查询条件
     * { matching  0 默认 1 精确匹配 2 模糊匹配,
     *  detailsType 0 默认 1 库存sku  3 中文名称 4 英文名称 ,
     *  message 查询内容,
     *  sku状态 0 全部 1 正常销售，2 停止销售，3 清仓}
     * @return
     */
    public List<ProductEasyExcelGroupAdd> batchDeriveExcelGroup(String body) {
        Integer matching = JacksonUtil.parseInteger(body, "matching");
        Integer detailsType = JacksonUtil.parseInteger(body, "detailsType");
        String message = JacksonUtil.parseString(body, "message");
        Integer skuState = JacksonUtil.parseInteger(body, "skuState");
        Integer categoryId = JacksonUtil.parseInteger(body, "categoryId");
        if (CheckoutUtil.isEmptyInteger(matching)) matching = null;
        if (CheckoutUtil.isEmptyInteger(detailsType)) detailsType = null;
        // 获取批量导出的数据
        List<ProductEasyExcelGroupAdd> listProduct = productMapper.batchDeriveExcelGroup(matching, detailsType, message, skuState, categoryId);
        List<Product> productList = productMapper.selectLinkListGroup(matching, detailsType, message, skuState, categoryId);
        for (ProductEasyExcelGroupAdd productEasyExcelGroupAdd : listProduct) {
            for (Product product : productList) {
                String skuList = "";
                List<ProductGroup> productGroupList = product.getProductGroupList();
                for (ProductGroup productGroup : productGroupList) {
                    skuList = skuList + productGroup.getProductParentSku() + ",";
                }
                if (productEasyExcelGroupAdd.getProductSku().equals(product.getProductSku())) {
                    productEasyExcelGroupAdd.setProductGroupSku(StringUtils.substringBeforeLast(skuList,","));
                }
            }
        }
        return listProduct;
    }

    /**
     * 批量导出选择的商品（组合商品）
     * @param list
     * @return
     */
    public List<ProductEasyExcelGroupAdd> batchDeriveExcelChoosesGroup(List<Integer> list) {
        // 获取批量导出的数据
        List<ProductEasyExcelGroupAdd> listProduct = productMapper.batchDeriveExcelChoosesGroup(list,list.get(CheckoutUtil.TYPE_ZERO));
        List<Product> productList = productMapper.selectLinkListGroupById(list,list.get(CheckoutUtil.TYPE_ZERO));
        for (ProductEasyExcelGroupAdd productEasyExcelGroupAdd : listProduct) {
            for (Product product : productList) {
                String skuList = "";
                List<ProductGroup> productGroupList = product.getProductGroupList();
                for (ProductGroup productGroup : productGroupList) {
                    skuList = skuList + productGroup.getProductParentSku() + ",";
                }
                if (productEasyExcelGroupAdd.getProductSku().equals(product.getProductSku())) {
                    productEasyExcelGroupAdd.setProductGroupSku(StringUtils.substringBeforeLast(skuList,","));
                }
            }
        }
        return listProduct;
    }

    /**
     * 批量导出(选择的商品)
     * @param list
     * @return
     */
    public List<ProductEasyExcelAdd> batchDeriveExcelChooses(List<Integer> list) {
        // 获取批量导出的数据
        return productMapper.batchDeriveExcelChooses(list,list.get(CheckoutUtil.TYPE_ZERO));
    }

    /**
     * 获取所有商品的id和sku
     * @return
     */
    public List<Product> selectListAll() {
        return productMapper.selectListAll();
    }

    /**
     * 批量添加
     * @param list
     * @return
     */
    public int insertSelectiveList(List<Product> list) {
        return productMapper.insertSelectiveList(list);
    }

    /**
     * 批量修改
     * @param list
     * @return
     */
    public int updateSelectiveList(List<Product> list) {
        return productMapper.updateSelectiveList(list);
    }

    /**
     * 生成条码和pdf文件
     * @param list 生成条码的商品sku和名称 集合
     * @param qrcodeLocalPathPng 本地png图片保存路径
     * @param qrcodeLocalPathPdf 本地pdf文件保存路径
     * @param fileServer 文件服务器地址
     * @return
     */
    public String barCodeProduct(List<String> list,String qrcodeLocalPathPng,String qrcodeLocalPathPdf,String fileServer) throws Exception {
        // 存放pdf文件
        List<String> listPdf = new ArrayList<>();
        // 获取生成pdf文件的商品信息
        List<Product> productList = this.productMapper.selectListPdf(list, list.get(0));
        // 判断sku是否正确
        if (list.size() != productList.size()) {
            throw new BizException(ErrorEnum.ErrorCode.authInvalidPassword);
        }
        for (Product barCodeProductVo : productList) {
            // BarCodeProductVo barCodeProductVo = list.get(0);
            String productSku = "SKU：" + barCodeProductVo.getProductSku();
            String productNameEn = barCodeProductVo.getProductNameEn();

            // --> 生成生成商品条码
            String barCode = String.format("PR%s", StringUtil.getRandomNum(5)); // 生成文件名称
            // String nameTwo = String.format("%s.png", barCode); // 文件名称带后缀
            BufferedImage image = BarCodeUtil.getBarCodeWithWords(barCode,barCode);
            // 本地图片存储完整路径
            String fileName = String.format(qrcodeLocalPathPng + "%s.png",barCode);
            // 生成条码,【保存到本地】
            ImageIO.write(image,"png", new File(fileName));

            //--> 生成pdf文件
            String barCodeTwo = String.format("%s", StringUtil.getRandomNum(5)); // 生成pdf文件名称的名称
            // 1. Document document = new Document();
            // 创建pdf模板
            Document document = PdfUtil.createDocument();
            String pdfPath = qrcodeLocalPathPdf + barCodeTwo + ".pdf";
            // 2. 获取writer
            PdfWriter.getInstance(document, new FileOutputStream(pdfPath));
            // PdfWriter.getInstance(document, new FileOutputStream("C:/Users/23026/Desktop/tempPdf/"+barCodeTwo+".pdf"));
            // PdfWriter.getInstance(document, os);
            // PDFWriter.getInstance(document,new FileOutputStream(“要存放的文件路径名”));
            // 3. open()
            document.open();

            //设置字体
            Font blackFont = PdfUtil.createFont(10, Font.NORMAL, BaseColor.BLACK);
            Font blueFont = PdfUtil.createFont(10, Font.NORMAL, BaseColor.BLUE);
            Font bigFont = PdfUtil.createFont(14, Font.NORMAL, BaseColor.BLACK);
            Font littleFont = PdfUtil.createFont(10, Font.NORMAL, BaseColor.BLACK);

            // 添加图片
            Image img = Image.getInstance(fileName);
            // Image img = Image.getInstance("C:\\Users\\23026\\Desktop\\tempPng\\PR36014.png");
            img.setAlignment(Element.ALIGN_CENTER);
            document.add(img);
            // 4. 添加段落内容
            Paragraph titleTwo = PdfUtil.createParagraph(productNameEn, bigFont);
            titleTwo.setAlignment(Element.ALIGN_LEFT);
            document.add(titleTwo);
            Paragraph titleThree = PdfUtil.createParagraph(productSku, bigFont);
            titleThree.setAlignment(Element.ALIGN_LEFT);
            document.add(titleThree);
            // 5. close()
            document.close();
            // 保存pdf文件存储地址
            listPdf.add(pdfPath);
        }
        // 合并pdf文件
        Map<String, String> map = PdfUtil.mergePdfFile(listPdf, qrcodeLocalPathPdf);
        // 【上传到文件服务器】
        String postPNG = OkHttpUtil.postPNG(fileServer, map.get("pdfNameOne"), map.get("pdfNameTwo"));
        log.info("{}postPNG=" + postPNG);// 打印日志
        // 解析返回结果，得到上传成功之后的阿里云pdf文件路径 http://...
        PNGUploadRespVo pdfUploadResp = JSONObject.parseObject(postPNG, PNGUploadRespVo.class);
        // String url = pdfUploadResp.getData();
        return pdfUploadResp.getData();
    }

    /**
     * 批量修改商品状态
     * @param list 商品sku集合
     * @param state 1 正常销售 2 停止销售 3 清仓
     * @return
     */
    public String updateProductStateBySku(List<String> list,Integer state){
        this.productMapper.updateProductStateBySku(list,state);
        return CheckoutUtil.TYPE_ONE.toString();
    }

}
